﻿#include "FITKFESubSysGeoProp.h"
#include "FITKAcousticsDiscModel.h"
#include "FITKAcousticsFEModel.h"
#include "FITKAcousticsDiscNodeList.h"
#include "FITKAbstractFESubSys.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKVec3DAlg.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Component/FITK2DMeshTools/FITKAbstractRecogClosedSpace.h"
#include <cmath>

namespace Acoustics
{
    FITKFESubSysGeoProp::FITKFESubSysGeoProp(FITKAbstractFESubSys* subsys)
        : _subSys(subsys)
    {
    }

    bool FITKFESubSysGeoProp::updateProp()
    {
        //错误判断
        if (_subSys == nullptr) return false;
        //子系统类型
        FITKAbstractFESubSys::FESubSysType t = _subSys->getFESubSysType();
        switch (t)
        {
            //结构
        case Acoustics::FITKAbstractFESubSys::FEStructure:
        {
            int dim = _subSys->getElementDim();
            if (dim == 1)
                this->calculateBeamStructureProp();
            else
                this->calculateShellStructureProp();
            break;
        }
            //腔体
        case Acoustics::FITKAbstractFESubSys::FEAcoustic:
            this->calculateAcousticProp();
            break;
        default: return false;
        }
        return true;
    }

    double FITKFESubSysGeoProp::getGeoProp(FESubSysGeoPropType t)
    {
        switch (t)
        {
        case Acoustics::FITKFESubSysGeoProp::Circumference: //周长
            return _geoprop[0];
        case Acoustics::FITKFESubSysGeoProp::Area:          //面积
            return _geoprop[1];
        case Acoustics::FITKFESubSysGeoProp::Volume:        //体积
            return _geoprop[2];
        default: break;
        }
        return 0;
    }

    void FITKFESubSysGeoProp::calculateBeamStructureProp()
    {
        if (!_subSys) return;
        //获取节点和网格数据
        QList<int> nodesIDList = _subSys->getNodesID();
        QList<int> elementsIDList = _subSys->getElementsID();
        if (nodesIDList.isEmpty() || elementsIDList.isEmpty())return;
        //获取节点管理器
        FITKAcousticsDiscModel *discModel = FITKAPP->getGlobalData()->getMeshData<FITKAcousticsDiscModel>();
        if (!discModel) return;
        FITKAcousticsDiscNodeList *discNodeList = discModel->getNodes();
        if (!discNodeList) return;
        //获取单元管理器
        FITKAcousticsFEModel* feModel = discModel->getFEModel();
        if (!feModel) return;
        FITKAcousticsFESubSysElementList* feElementList = feModel->getFESubSysElementList();
        if (!feElementList) return;
        //计算周长
        double Circumference = 0.0;
        for (int eID : elementsIDList)
        {
            Interface::FITKAbstractElement* element = feElementList->getElementByID(eID);
            if (!element) continue;
            QList<int> nodeIDs = element->getAllNodes();
            if (nodeIDs.size() < 2) continue;
            Core::FITKNode *node1 = discNodeList->getNodeByID(nodeIDs.at(0)), *node2 = discNodeList->getNodeByID(nodeIDs.last());
            if (!node1 || !node2)continue;
            Core::FITKPoint subData = Core::Subtract(*node1, *node2);
            Core::FITKVec3D vecData(subData);
            Circumference += vecData.getNorm();
        }
        _geoprop[0] = Circumference;
    }

    void FITKFESubSysGeoProp::calculateShellStructureProp()
    {
        if (!_subSys) return;
        //获取节点和网格数据
        QList<int> nodesIDList = _subSys->getNodesID();
        QList<int> elementsIDList = _subSys->getElementsID();
        if (nodesIDList.isEmpty() || elementsIDList.isEmpty())return;
        //获取节点管理器
        FITKAcousticsDiscModel *discModel = FITKAPP->getGlobalData()->getMeshData<FITKAcousticsDiscModel>();
        if (!discModel) return;
        FITKAcousticsDiscNodeList *discNodeList = discModel->getNodes();
        if (!discNodeList) return;
        //获取单元管理器
        FITKAcousticsFEModel* feModel = discModel->getFEModel();
        if (!feModel) return;
        FITKAcousticsFESubSysElementList* feElementList = feModel->getFESubSysElementList();
        if (!feElementList) return;
        //存储点和单元
        QList<Core::FITKNode*> nodeList;
        QList<Interface::FITKAbstractElement*> eleList;
        //获取节点数据
        for (int nID : nodesIDList)
        {
            Core::FITKNode *node = discNodeList->getNodeByID(nID);
            if (!node)continue;
            nodeList.append(node);
        }
        //获取单元数据
        for (int eID : elementsIDList)
        {
            Interface::FITKAbstractElement* ele = feElementList->getElementByID(eID);
            if (!ele) continue;
            eleList.append(ele);
        }
        //获取边界数据
        //Interface::FITKAbstractRecogClosedSpace * space = Interface::FITKAbstractRecogClosedSpace::createFITKRecogClosedSpace();
        //if (!space->initMesh(nodeList, eleList)) return;
        //QList<QPair<int, int>> bound = space->getBoundary();
        //for (QList<QPair<int, int>>::iterator iter = bound.begin(); iter < bound.end(); ++iter)
        //{
        //    int nodeIndex1 = iter->first, nodeIndex2 = iter->second;
        //    if (nodeList.size() <= nodeIndex1 || nodeList.size() <= nodeIndex2)continue;
        //    Core::FITKNode *node1 = nodeList.at(nodeIndex1), *node2 = nodeList.at(nodeIndex2);
        //    if (!node1 || !node2)continue;
        //    int node1ID = node1->getNodeID();
        //    int node2ID = node2->getNodeID();
        //    _boundaryNodes.append(QPair<int, int>(node1ID, node2ID));
        //}
        //delete space;

    }

    void FITKFESubSysGeoProp::calculateAcousticProp()
    {

    }
}


